package com.jackrain.nea.ad.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.jackrain.nea.ad.api.CmenuSaveCmd;
import com.jackrain.nea.ad.entity.MenuEntity;
import com.jackrain.nea.ad.utility.MenuManager;
import com.jackrain.nea.ext.permission.MenuType;
import com.jackrain.nea.ad.mapper.CmenuMapper;
import com.jackrain.nea.config.Resources;
import com.jackrain.nea.core.schema.Table;
import com.jackrain.nea.core.webaction.WebAction;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.sys.CommandAdapter;
import com.jackrain.nea.util.ApplicationContextHandle;
import com.jackrain.nea.util.ValueHolder;
import com.jackrain.nea.utility.ServiceUtil;
import com.jackrain.nea.utility.StringUtil;
import com.jackrain.nea.web.query.DefaultWebEvent;
import com.jackrain.nea.web.query.QuerySession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;

/**
 * @author lzm
 * @date 2017-11-16
 */
@Slf4j
@Component
@Service(protocol = "dubbo", validation = "true", version = "1.0", group = "ad")
public class CmenuSaveCmdImpl extends CommandAdapter implements CmenuSaveCmd {
    private static String MENU_TABLE_NAME = "AD_MENU";

    @Override
    public ValueHolder execute(QuerySession session) throws NDSException {
        DefaultWebEvent event = session.getEvent();
        JSONObject param = JSON.parseObject(JSON.toJSONStringWithDateFormat(event.getParameterValue("param"), "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue), Feature.OrderedField);
        JSONObject rows = param.getJSONObject("fixcolumn");
        if (rows == null) {
            throw new NDSException(Resources.getMessage("新增、更新时需传入对应数据！", session.getLocale()));
        }
        JSONObject mainRow = rows.getJSONObject(MENU_TABLE_NAME);
        if (mainRow == null) {
            throw new NDSException(StringUtil.formatWithLocal(session.getLocale(), "新增、更新时要传入%s表更新内容！", "AD_MENU"));
        }
        Long id = param.getLong("objid");
        Timestamp now = new Timestamp(System.currentTimeMillis());
        CmenuMapper dal = ApplicationContextHandle.getBean(CmenuMapper.class);
        if (id == null || id <= 0) {
            //新增
            MenuType type = MenuType.valueOf(mainRow.getInteger("TYPE"));
            if (type == null || (type != MenuType.TABLE && type != MenuType.ACTION)) {
                throw new NDSException(StringUtil.formatWithLocal(session.getLocale(), "表类型不可识别！"));
            }
            if (type == MenuType.TABLE) {
                beforeInsertTable(session, dal, mainRow);
            } else {
                beforeInsertAction(session, dal, mainRow);
            }
            id = ServiceUtil.fillDefaultValuesBeforeInsert(MENU_TABLE_NAME, session, mainRow, now);
            dal.insertMenu(mainRow);
        } else {
            //修改
            MenuEntity oldEntity = dal.getMenuById(id);
            if(oldEntity == null){
                throw new NDSException(StringUtil.formatWithLocal(session.getLocale(), "当前记录已不存在！"));
            }
            MenuType type = MenuType.valueOf(mainRow.getInteger("TYPE"));
            if (!mainRow.containsKey("TYPE")) {
                type = MenuType.valueOf(oldEntity.getType());
            }

            if (type == null || (type != MenuType.TABLE && type != MenuType.ACTION)) {
                throw new NDSException(StringUtil.formatWithLocal(session.getLocale(), "表类型不可识别！"));
            }
            if (type == MenuType.TABLE) {
                beforeUpdateTable(session, dal, oldEntity, mainRow, id);
            } else {
                beforeUpdateAction(session, dal, oldEntity, mainRow, id);
            }

            ServiceUtil.fillDefaultValuesBeforeUpdate(MENU_TABLE_NAME, session, id, mainRow, now);
            dal.updateMenu(mainRow);
        }

        //更新下menuTree
        List<MenuEntity> allMenus = dal.fetchAllMenus();
        List<HashMap<String, Long>> allMenuActions = dal.fetchAllActions();
        MenuManager.updateAll(session, allMenus, allMenuActions);
        ValueHolder result = new ValueHolder();
        JSONObject data = new JSONObject();
        data.put("tablename", MENU_TABLE_NAME);
        data.put("objid", id);
        result.put("data", data);

        result.put("code", 0);
        result.put("message", Resources.getMessage("保存成功", session.getLocale()));
        return result;
    }

    private void beforeInsertTable(QuerySession session, CmenuMapper dal, JSONObject mainRow) {
        Long tableId = mainRow.getLong("AD_TABLE_ID");
        Table table = null;
        if (tableId != null && tableId > 0) {
            table = session.getTableManager().getTable(tableId.intValue());
        }
        if (table == null) {
            throw new NDSException(StringUtil.formatWithLocal(session.getLocale(), "表不能为空"));
        }
        if (dal.countMenuByTable(tableId, -1L) > 0) {
            throw new NDSException(StringUtil.formatWithLocal(session.getLocale(), "输入的数据已存在：表"));
        }
        Integer temp = mainRow.getInteger("AD_SUBSYSTEM_ID");
        if (temp == null || temp <= 0) {
            mainRow.put("AD_SUBSYSTEM_ID", table.getCategory().getSubSystem().getId());
        }
        temp = mainRow.getInteger("AD_TABLECATEGORY_ID");
        if (temp == null || temp <= 0) {
            mainRow.put("AD_TABLECATEGORY_ID", table.getCategory().getId());
        }
        temp = mainRow.getInteger("ORDERNO");
        if (temp == null || temp <= 0) {
            mainRow.put("ORDERNO", table.getOrder());
        }
        mainRow.put("AD_ACTION_ID", null);
    }

    private void beforeUpdateTable(QuerySession session, CmenuMapper dal, MenuEntity oldEntity, JSONObject mainRow, Long id) {
        Long tableId = mainRow.getLong("AD_TABLE_ID");
        Table table = null;
        if (!mainRow.containsKey("AD_TABLE_ID")) {
            tableId = oldEntity.getAd_table_id();
        }
        if (tableId != null && tableId > 0) {
            table = session.getTableManager().getTable(tableId.intValue());
        }
        if (dal.countMenuByTable(tableId, id) > 0) {
            throw new NDSException(StringUtil.formatWithLocal(session.getLocale(), "输入的数据已存在：表"));
        }
        if (table == null) {
            throw new NDSException(StringUtil.formatWithLocal(session.getLocale(), "表不能为空"));
        }
        Integer temp = mainRow.getInteger("AD_SUBSYSTEM_ID");
        if (mainRow.containsKey("AD_SUBSYSTEM_ID") && (temp == null || temp <= 0)) {
            mainRow.put("AD_SUBSYSTEM_ID", table.getCategory().getSubSystem().getId());
        }
        temp = mainRow.getInteger("AD_TABLECATEGORY_ID");
        if (mainRow.containsKey("AD_TABLECATEGORY_ID") && (temp == null || temp <= 0)) {
            mainRow.put("AD_TABLECATEGORY_ID", table.getCategory().getId());
        }

        mainRow.put("AD_ACTION_ID", null);
    }

    private void beforeInsertAction(QuerySession session, CmenuMapper dal, JSONObject mainRow) {
        Long actionId = mainRow.getLong("AD_ACTION_ID");
        WebAction action = null;
        if (actionId != null && actionId > 0) {
            action = session.getTableManager().getWebAction(actionId.intValue());
        }
        if (dal.countMenuByAction(actionId, -1L) > 0) {
            throw new NDSException(StringUtil.formatWithLocal(session.getLocale(), "输入的数据已存在：动作定义"));
        }
        if (action == null) {
            throw new NDSException(StringUtil.formatWithLocal(session.getLocale(), "动作定义不能为空"));
        }

        Integer temp = mainRow.getInteger("AD_SUBSYSTEM_ID");
        if (temp == null || temp <= 0) {
            mainRow.put("AD_SUBSYSTEM_ID", action.getSubSystemId());
        }
        temp = mainRow.getInteger("AD_TABLECATEGORY_ID");
        if (temp == null || temp <= 0) {
            mainRow.put("AD_TABLECATEGORY_ID", action.getTableCategoryId());
        }

        temp = mainRow.getInteger("ORDERNO");
        if (temp == null || temp <= 0) {
            mainRow.put("ORDERNO", action.getOrder());
        }
        mainRow.put("AD_TABLE_ID", null);
    }

    private void beforeUpdateAction(QuerySession session, CmenuMapper dal, MenuEntity oldEntity, JSONObject mainRow, Long id) {
        Long actionId = mainRow.getLong("AD_ACTION_ID");
        WebAction action = null;
        if (!mainRow.containsKey("AD_ACTION_ID")) {
            actionId = oldEntity.getAd_action_id();
        }
        if (actionId != null && actionId > 0) {
            action = session.getTableManager().getWebAction(actionId.intValue());
        }
        if (dal.countMenuByAction(actionId, id) > 0) {
            throw new NDSException(StringUtil.formatWithLocal(session.getLocale(), "输入的数据已存在：动作定义"));
        }
        if (action == null) {
            throw new NDSException(StringUtil.formatWithLocal(session.getLocale(), "动作定义不能为空"));
        }

        Integer temp = mainRow.getInteger("AD_SUBSYSTEM_ID");
        if (mainRow.containsKey("AD_SUBSYSTEM_ID") && (temp == null || temp <= 0)) {
            mainRow.put("AD_SUBSYSTEM_ID", action.getSubSystemId());
        }
        temp = mainRow.getInteger("AD_TABLECATEGORY_ID");
        if (mainRow.containsKey("AD_TABLECATEGORY_ID") && (temp == null || temp <= 0)) {
            mainRow.put("AD_TABLECATEGORY_ID", action.getTableCategoryId());
        }
        mainRow.put("AD_TABLE_ID", null);
    }
}
